import React from 'react';
import PropTypes from 'prop-types';
import css from './index.less';
import { observer } from 'mobx-react';
import EVENTS from 'common/const/events';
import ACTIONS from 'common/const/events/actions';
import Options from './components/options';
import Portal from 'components/portal';

import ToLink from './toLink';
import ToPage from './toPage';
import ToMotion from './toMotion';

const findLabelWithKey = (key, array) => {
  let rs = '';
  for (let i = 0; i < array.length; i++) {
    const item = array[i];
    if (item.key === key) {
      rs = item.label;
      break;
    }
  }
  return rs;
};

@observer
export default class Event extends React.Component {
  static propTypes = {
    mod: PropTypes.object.isRequired,
    event: PropTypes.object,
  };

  rect = null;

  constructor(props) {
    super(props);

    const { eventKey, actionKey, actionDetail } = props.event;
    this.state = {
      isOpen: false,
      step: 0,
      changeTag: 0,

      // Event model 属性
      eventKey,
      actionKey,
      actionDetail,
    };
  }

  componentDidMount() {
    setTimeout(() => {
      this.rect = this.refs.node.getBoundingClientRect();
    }, 5);
  }

  renderPopover() {
    if (!this.rect) return <div />;

    const props = {
      className: css.popover,
      style: {
        top: this.rect.bottom + 5,
        left: this.rect.left,
      }
    };

    return (
      <div {...props}>
        {this.renderPopoverStep1()}
        {this.renderPopoverStep2()}
        {this.renderPopoverStep3()}
      </div>
    );
  }

  // 第一步 选择事件
  renderPopoverStep1() {
    const { event, mod } = this.props;
    const { eventKey } = this.state;
    const options = [...EVENTS].map(op => {
      op.selected = eventKey && eventKey === op.key;
      op.disabled = false;
      mod.events.forEach(ev => {
        if (ev.eventKey === op.key) {
          op.disabled = true;
        }
      });
      return op;
    });
    const props = {
      options,
      onChange: (item) => {
        const changed = {
          eventKey: item.key,
          actionKey: '',
          actionDetail: '',
        };
        event.update(changed);
        this.setState({
          step: 1,
          ...changed,
        });
      }
    };

    return (
      <Options {...props} />
    );
  }

  // 第二步 选择动作
  renderPopoverStep2() {
    const { event } = this.props;
    const { step, actionKey } = this.state;
    if (step === 0 ) return null;
    const options = [...ACTIONS].map(op => {
      op.selected = actionKey && actionKey === op.key;
      return op;
    });
    const props = {
      options,
      onChange: (item) => {
        const changed = {
          actionKey: item.key,
          actionDetail: '',
        };
        event.update(changed);
        this.setState({
          step: 2,
          ...changed,
        });
      }
    };

    return (
      <Options {...props} />
    );
  }

  // 第三步 选择动作详情 todo
  renderPopoverStep3() {
    const { event: { actionDetail } } = this.props;
    const { step, actionKey } = this.state;
    if (step <= 1 ) return null;
    const props = {
      className: css.actionDetail,
    };

    // const Comp = _props => lazilyComponent(import(`components/config/events/event/${actionKey}`))(_props);
    // 此处不能用 lazilyComponent ，比较悲伤。
    const actionDetailProps = {
      actionDetail,
      onChange: (val, isOpen = true) => {
        // console.log('event onChange val', val);
        this.setState({
          isOpen,
          step: 3,
          actionDetail: val,
        });
      },
    };

    const renderActionDetail = () => {
      switch (actionKey) {
        case 'toLink': {
          return <ToLink {...actionDetailProps}/>;
        }
        case 'toPage': {
          return <ToPage {...actionDetailProps}/>;
        }
        case 'toMotion': {
          return <ToMotion {...actionDetailProps}/>;
        }
        default: {
          return (
            <div style={{padding: 15}}> 未找到 "{findLabelWithKey(actionKey, ACTIONS)}" 对应的渲染组件 </div>
          );
        }
      }


    };

    return (
      <div {...props}>
        {renderActionDetail()}
      </div>
    );

  }

  renderCell() {
    const { eventKey, actionKey, actionDetail } = this.props.event;
    const props = {
      className: css.box,
      ref: 'node',
    };

    if (!eventKey || !actionKey || !actionDetail) {
      return (
        <div {...props} >
          <div className={css.placeholder}>请选择事件...</div>
        </div>
      );
    }
    return (
      <div {...props} >
        <div className={css.cell}>{findLabelWithKey(eventKey, EVENTS)}</div>
        <div className={css.cell}>{findLabelWithKey(actionKey, ACTIONS)}</div>
        <div className={css.cell}>
          {
            typeof actionDetail === 'string' ? actionDetail : actionDetail.title
          }
        </div>
      </div>
    );
  }

  renderPortal() {
    const { event } = this.props;
    const portalProps = {
      portalTrigger: this.refs.portalTrigger,
      isOpen: this.state.isOpen,
      closeOnEsc: true,
      closeOnOutsideClick: true,
      onClose: () => {
        let { eventKey, actionKey, actionDetail, step } = this.state;
        // 如果有一项未选中，则重置状态
        if (!eventKey || !actionKey || !actionDetail) {
          step = 0;
        } else {
          event.update({
            eventKey,
            actionKey,
            actionDetail,
          });
        }

        this.setState({
          isOpen: false,
          step,
        });
      },
    };
    return (
      <Portal {...portalProps}>
        {
          this.renderPopover()
        }
      </Portal>
    );
  }


  render() {
    const props = {
      onClick: () => {
        this.setState({
          isOpen: true,
        });
      },
      ref: 'portalTrigger',
    };

    return (
      <div {...props}>
        {this.renderCell()}
        {this.renderPortal()}
      </div>
    );
  }
}
